package com.atmilan.quartz.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import com.atmilan.quartz.utils.product.LavitaProductUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atmilan.quartz.constant.Constants;
import com.atmilan.quartz.constant.enums.ProductTypeEnum;
import com.atmilan.quartz.constant.enums.SyncStatusEnum;
import com.atmilan.quartz.model.dto.crmeb.StoreProductCrmebRequest;
import com.atmilan.quartz.model.dto.lavita.LavitaProductResDTO;
import com.atmilan.quartz.model.dto.lavita.LavitaProductResDTO.Product;
import com.atmilan.quartz.model.dto.lavita.LavitaProductSkuRes;
import com.atmilan.quartz.model.dto.lavita.LavitaProductSkuResDTO.Detail;
import com.atmilan.quartz.model.dto.lavita.LavitaProductStockRes;
import com.atmilan.quartz.model.entity.crmeb.CategoryMatch;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.crmeb.SystemConfig;
import com.atmilan.quartz.model.entity.lavita.LavitaProduct;
import com.atmilan.quartz.model.entity.lavita.LavitaProductSku;
import com.atmilan.quartz.service.ICategoryMatchService;
import com.atmilan.quartz.service.ILavitaProductService;
import com.atmilan.quartz.service.ILavitaProductSkuService;
import com.atmilan.quartz.service.ILavitaSyncService;
import com.atmilan.quartz.service.IStoreProductAttrService;
import com.atmilan.quartz.service.IStoreProductAttrValueService;
import com.atmilan.quartz.service.IStoreProductService;
import com.atmilan.quartz.service.ISystemConfigService;
import com.atmilan.quartz.utils.BeanCopyUtil;
import com.atmilan.quartz.utils.RedisUtil;
import com.atmilan.quartz.utils.source.SourceLavitaProductUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Howe Hsiang
 */
@Slf4j
@Service
public class LavitaSyncServiceImpl implements ILavitaSyncService {
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    ISystemConfigService systemConfigService;
    @Autowired
    ILavitaProductService lavitaProductService;
    @Autowired
    ILavitaProductSkuService lavitaProductSkuService;
    @Autowired
    IStoreProductService storeProductService;
    @Autowired
    IStoreProductAttrService storeProductAttrService;
    @Autowired
    IStoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    SourceLavitaProductUtil sourceLavitaProductUtil;
    @Autowired
    ICategoryMatchService categoryMatchService;
    @Autowired
    LavitaProductUtil lavitaProductUtil;
    
    /**
     * 获取远程数据并保存到数据源
     */
    @Override
    public Boolean syncProduct() {
        // 数据清空
        lavitaProductService.deleteAll();
        lavitaProductSkuService.deleteAll();

        int pageNo = 1;
        int page = 0;
        int pageSize = 50;

        int count = 1;
        int pageCount = (count + pageSize - 1) / pageSize;
        long millis = System.currentTimeMillis();
        while(page <= pageCount) {
            try {
                LavitaProductResDTO lavitaProductResDTO = lavitaProductUtil.selectLavitaPage(pageNo,pageNo+pageSize-1);
                if(null == lavitaProductResDTO||ObjectUtils.isEmpty(lavitaProductResDTO.getDataJson())) {
                    log.info("--------------- lavita获取商品接口请求失败 ---------------");
                    continue;
                }
                count = lavitaProductResDTO.getDataJson().getTotalRecs();
                pageCount = (count + pageSize - 1) / pageSize;
                List<Detail> detailList = new ArrayList<>();
                List<Product> productList = lavitaProductResDTO.getDataJson().getProductList();
                if (productList.size() == 0) {
                    return true;
                }
                List<Product> cProductList = new ArrayList<>();
                for (Product product:productList){
                    LavitaProductSkuRes lavitaProductSkuRes = lavitaProductUtil.getLavitaSku(product.getKuanId());
                    LavitaProductStockRes lavitaProductStockRes = new LavitaProductStockRes();
                    if (ObjectUtils.isNotNull(lavitaProductSkuRes)&&ObjectUtils.isNotNull(lavitaProductSkuRes.getDataDetail())) {
                        lavitaProductStockRes = lavitaProductUtil.getLavitaDetail(lavitaProductSkuRes.getDataDetail().getKuan());
                    }
                    BeanUtils.copyProperties(lavitaProductSkuRes.getDataDetail(),product);
                    if (ObjectUtils.isNotEmpty(lavitaProductSkuRes.getDataDetail().getColors())) {
                        product.setColors(lavitaProductSkuRes.getDataDetail().getColors().toString());
                    }
                    if (ObjectUtils.isNotEmpty(lavitaProductSkuRes.getDataDetail().getSizes())) {
                        product.setSizes(lavitaProductSkuRes.getDataDetail().getSizes().toString());
                    }
                    if (ObjectUtils.isNotEmpty(lavitaProductSkuRes.getDataDetail().getImgList())) {
                        product.setImgList(lavitaProductSkuRes.getDataDetail().getImgList().toString());
                    }
                    if (ObjectUtils.isNotEmpty(lavitaProductSkuRes.getDataDetail().getImgDetail())) {
                        product.setImgDetail(lavitaProductSkuRes.getDataDetail().getImgDetail().toString());
                    }
                    cProductList.add(product);
                    if(!Objects.isNull(lavitaProductSkuRes) && !Objects.isNull(lavitaProductSkuRes.getDataDetail()) &&
                            CollectionUtils.isNotEmpty(lavitaProductSkuRes.getDataDetail().getProductList())){
                        for (LavitaProductSkuRes.Detail.Product e : lavitaProductSkuRes.getDataDetail().getProductList()) {

                            Detail detail = new Detail();
                            BeanUtils.copyProperties(e, detail);
                            if (lavitaProductStockRes!=null&&lavitaProductStockRes.getSkus()!=null){
                                lavitaProductStockRes.getSkus().stream().forEach(j->{
                                    if (j.getSkuCode()!=null&&j.getSkuCode().equals(detail.getSkuCode())) {
                                        BeanUtils.copyProperties(j, detail);
                                    }
                                });
                            }

                            detail.setKuanId(product.getKuanId());
                            AtomicReference<String> color = new AtomicReference();
                            List<JSONObject> colors = lavitaProductSkuRes.getDataDetail().getColors();
                            List<JSONObject> sizes = lavitaProductSkuRes.getDataDetail().getSizes();
                            colors.stream().forEach(q -> {
                                if (q.get("colorId").equals(e.getColorId())) {
                                    color.set(q.get("color").toString());
                                }
                            });
                            AtomicReference<String> size = new AtomicReference();
                            sizes.stream().forEach(q -> {
                                if (q.get("sizeId").equals(e.getSizeId())) {
                                    size.set(q.get("size").toString());
                                }
                            });

                            detail.setColor(color.get());
                            detail.setSize(size.get());
                            detailList.add(detail);
                        }
                    }
                };
                /*if(CollectionUtils.isEmpty(detailList)) {
                    log.info("--------------- lavita获取商品接口请求失败 ---------------");
                    continue;
                }*/
                
                // 商品保存
                saveProductList(cProductList, detailList);
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("--------------- lavita远程抓取数据, 第: {} 页, 共: {} 页, 总耗时: {} 分  ---------------", page+1,pageCount,(int)((System.currentTimeMillis() - millis) / 1000 / 60));
            pageNo+=pageSize;
            page++;
        }
        return true;
    }
    
    // 商品源数据保存
    private void saveProductList(List<LavitaProductResDTO.Product> goodsList, List<Detail> detailList) {
        // 商品数据
        List<LavitaProduct> goodsEntity = new ArrayList<>();
        for(LavitaProductResDTO.Product product : goodsList) {
            LavitaProduct productEntity = new LavitaProduct();
            BeanUtils.copyProperties(product, productEntity);
            productEntity.setColors(product.getColors());
            productEntity.setCreateTime(new Date());
            goodsEntity.add(productEntity);
        }
        List<LavitaProductSku> productSkuEntity = BeanCopyUtil.copyListProperties(detailList, LavitaProductSku::new,(detail,productSku)->{
            productSku.setCreateTime(new Date());
        });
        lavitaProductService.saveBatch(goodsEntity);
        lavitaProductSkuService.saveBatch(productSkuEntity);
    }

    @Override
    public Boolean pushProduct() {
        try {
            // 当次更新少于1千条, 则不更新, 并且重新拉取
            int count = lavitaProductService.count();
            if(500 > count) {
                systemConfigService.update(Wrappers.<SystemConfig>lambdaUpdate()
                        .eq(SystemConfig :: getName, Constants.LAVITA_SYNC_STATUS)
                        .set(SystemConfig :: getFormId, SyncStatusEnum.PUSH)
                        .set(SystemConfig :: getUpdateTime, new Date())
                        );
                log.info("--------------- lavita商品源数据, 少于规定条数, 不进行下发, 总条数为: {} ---------------", count);
                return false;
            }
            
            // 将所有lavita商品更新状态置为未更新
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct :: getIsEurope, ProductTypeEnum.LAVITA.getCode())
                    .set(StoreProduct :: getUpdateFlag, false)
                    );
            
            // 商品更新操作
            int pageNo = 1;
            int pageSize = 100;
            int maxPage = (count + pageSize - 1) / pageSize;
            log.info("--------------- 开始分页查询lavita商品源数据, 本次更新总条数为: {} ---------------", count);

            long millis = System.currentTimeMillis();
            while (pageNo <= maxPage) {
                try {
                    PageHelper.startPage(pageNo, pageSize);
                    List<LavitaProduct> lavitaProducts = lavitaProductService.list(Wrappers.<LavitaProduct>lambdaQuery().eq(LavitaProduct::getIsHide,0));
                    PageInfo<LavitaProduct> pageInfo = PageInfo.of(lavitaProducts);
                    List<LavitaProduct> products = pageInfo.getList();
                    buildProduct(products);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                log.info("--------------- lavita下发商品到数据库, 当前页数: {}, 总页数: {}, 耗时: {} 分 ---------------", pageNo, maxPage, (int)((System.currentTimeMillis() - millis) / 1000 / 60));
                pageNo++;
            }
            // 图搜删除
            storeProductService.delSeachImage(ProductTypeEnum.LAVITA);
            // 下架所有未更新数据
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getIsEurope, ProductTypeEnum.LAVITA.getCode())
                    .eq(StoreProduct::getUpdateFlag, false)
                    .eq(StoreProduct :: getIsShow, true)
                    .eq(StoreProduct :: getIsDel, false)
                    .set(StoreProduct::getIsShow, false)
                    .set(StoreProduct::getStock, 0)
                    .set(StoreProduct::getLastPushTime, new Date())
                    .set(StoreProduct::getIsTusou, false)
                    );
            // 下架所有sku库存
            storeProductService.downloadSku(ProductTypeEnum.LAVITA.getCode());

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return false;
    }

    /**
     * 商品构建处理
     * @Description:  
     * @author songjc
     * @param @param products
     * @return void
     * @throws
     */
    private void buildProduct(List<LavitaProduct> products) {
        try {
            for (LavitaProduct product : products) {
                List<LavitaProductSku> skus = lavitaProductSkuService.list(Wrappers.<LavitaProductSku>lambdaQuery()
                        .eq(LavitaProductSku :: getKuanId, product.getKuanId())
                        .eq(LavitaProductSku :: getIsHide, 0)
                        .isNotNull(LavitaProductSku::getSize)
                        .gt(LavitaProductSku :: getQtyAvail, 0)
                        );
                if (CollectionUtils.isEmpty(skus)) {
                    continue;
                }
                // 库存计算
                int stock = skus.stream().filter(e -> ObjectUtils.isNotNull(e.getQtyAvail())).mapToInt(LavitaProductSku::getQtyAvail).sum();
                if (ObjectUtils.isEmpty(product.getImgList()) || CollectionUtils.isEmpty(JSONArray.parseArray(product.getImgList(),String.class)) || ObjectUtils.isEmpty(product.getImg())) {
                    log.info("--------------- 该商品: {} 没有图片, 不进行下放 ---------------", product.getKuanId());
                    continue;
                }

                // 构建实体
                StoreProductCrmebRequest storeProductCrmebRequest = sourceLavitaProductUtil.buildLavitaProduct(product, skus);
                // 数据保存
                StoreProduct storeProduct = storeProductService.getByBarCode(storeProductCrmebRequest.getBarCode(), storeProductCrmebRequest.getSuppliersId(), storeProductCrmebRequest.getKeyword());
                boolean crmebUpdate = true;
                if (null != storeProduct && null != storeProduct.getLastPushTime()) {
                    long time = (System.currentTimeMillis() - storeProduct.getLastPushTime().getTime()) / 1000 / 60;
                    if (60 > time) {
                        log.info("--------------- 该商品: {} 上次lavita更新时间: {} 小于一小时, 不进行更新 ---------------", storeProductCrmebRequest.getBarCode(), storeProduct.getLastPushTime());
                        crmebUpdate = false;
                        storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                                .eq(StoreProduct::getId, storeProduct.getId())
                                .set(StoreProduct::getUpdateFlag, true)
                                );
                    }
                }
                if (crmebUpdate) {
                    storeProductService.saveOtProduct(storeProductCrmebRequest, storeProduct, stock);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void changeProduct() {
        int count = storeProductService.count(Wrappers.<StoreProduct>lambdaQuery()
                .eq(StoreProduct :: getIsEurope, 9)
                );
        int pageSize = 100;
        int maxPage = (count + pageSize - 1) / pageSize;
        for(int i=0; i<=maxPage; i++) {
            PageHelper.startPage(i, pageSize);
            List<StoreProduct> storeProducts = storeProductService.list(Wrappers.<StoreProduct>lambdaQuery()
                .eq(StoreProduct :: getIsEurope, 9)
                );
            PageInfo<StoreProduct> pageInfo = PageInfo.of(storeProducts);
            List<StoreProduct> products = pageInfo.getList();
            for(StoreProduct product : products) {
                String name = product.getStoreName().replace("\"", "");
                String[] infos = StringUtils.isEmpty(product.getStoreInfo()) ? new String[0] : product.getStoreInfo().split("\n");
                
                CategoryMatch nameMatch = categoryMatchService.getOne(Wrappers.<CategoryMatch>lambdaQuery()
                        .eq(CategoryMatch :: getType, 0)
                        .eq(CategoryMatch :: getCategoryName, name)
                        .last("LIMIT 1")
                        );
                String storeName = null == nameMatch ? product.getStoreName() : nameMatch.getOthCategoryName();
                StringBuilder sb = new StringBuilder();
                for(int z=0; z<infos.length; z++) {
                    CategoryMatch infoMatch = categoryMatchService.getOne(Wrappers.<CategoryMatch>lambdaQuery()
                            .eq(CategoryMatch :: getType, 1)
                            .eq(CategoryMatch :: getCategoryName, infos[z])
                            .last("LIMIT 1")
                            );
                    sb.append(null == infoMatch ? infos[z] : infoMatch.getOthCategoryName());
                    if(z+1 < infos.length) {
                        sb.append("\n");
                    }
                }
                
                storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                        .eq(StoreProduct :: getId, product.getId())
                        .set(StoreProduct :: getStoreName, storeName)
                        .set(StoreProduct :: getStoreInfo, sb.toString())
                        );
            }
            
        }
        
        
    }

}
